/*
 * 多路径合并计算（双向同步）
 * 1. 列过滤：根据 $condition / $terms 计算 $qr
 * 2. 搜索框：根据 $condition / $terms 计算 $qr
 * 3. 高级搜索提交：根据 $qr / $terms 计算 $condition
 *
 * $qr 会用于查询视图、高级搜索表单两个地方
 * 视图选择时修改 $queryView 构造最新的值
 */
import {QQuery} from 'zmr';
import __Zn from './zero.module.dependency';
import __QRP from './query.__.fn.qr.processor';

const __qrKeyword = (state = {}, configuration = {}) => {
    const {
        $terms = {},
        $condition = {}
    } = configuration;
    // 关键字高亮
    const $keyword = {};
    Object.keys($terms).forEach(field => {
        const config = $terms[field];
        if ("SEARCH" === config.type && $condition.hasOwnProperty(field)) {
            const keyword = $condition[field];
            $keyword[field] = keyword[0];   // 此处 keyword 必定是 []
        }
    });
    state.$keyword = $keyword;
}
/*
 * 1) $condition -> $qr（合并原始） -> $keyword
 * 2) $qr（替换） -> $condition    -> $keyword
 *
 * 流程处理（入口函数注释 #QR-COMMENT）
 * 入口：列过滤：$condition（合并）-> 1)
 * 入口：输入框：$condition（替换）-> 1)
 * 入口：高级搜索：$qr（替换）
 * 入口：查询条件：$queryView -> $qr（清空，限制列过滤）
 */
const __qrFromCondition = (conditionInput = {}, state = {}, isAppend = true) => {
    let condition = __Zn.clone(conditionInput);
    let {
        $condition = {},
        $terms,
        $qr,
    } = state;
    if (isAppend) {
        $condition = __Zn.clone($condition);
        condition = Object.assign($condition, condition);
    }
    const response = {};
    response.$condition = condition;
    __qrKeyword(response, {
        $condition: condition,
        $terms,
    });

    /*
     * 此处计算 $qr 不考虑 isAppend 参数，由于 condition 已经
     * 计算过一次，所以此处的 $qr 可直接根据 condition 执行计算
     * 低优先级往高优先级执行可以直接使用替换合并的模式处理
     */
    let qr = $qr ? __Zn.clone($qr) : {};
    const qrNorm = __QRP.qrNorm(condition, {terms: $terms, strict: false});
    Object.assign(qr, qrNorm);
    qr.connector = qr[""] && __Zn.isNotEmpty(qrNorm) ? "AND" : "OR";
    delete qr[""];
    response.$qr = qr;
    return response;
}
const irData = (reference) => (params = {}) => {
    let {
        $queryView = {},        // 默认查询条件
        $terms,                 // 列过滤处理
    } = reference.state;
    const {
        $condition = {},        // 传入的查询条件,
        isQrC = false,
        isAppend = false,
    } = params;

    const state = __qrFromCondition($condition, reference.state, isAppend);
    if (isQrC) {
        state.$qr = {connector: "AND"}
    }
    $queryView = __Zn.clone($queryView);
    const queryRef = new QQuery($queryView, reference);
    const queryCond = __QRP.qrNorm(state.$condition, {terms: $terms});
    queryRef.and(queryCond);
    return [state, queryRef];
};
const __qrFromForm = (qrInput = {}, state = {}) => {
    let qr = __Zn.clone(qrInput);
    let {
        $condition = {},
        $terms = {},
    } = state;
    const response = {};
    /*
     * 此处计算 $qr 一定是替换（高优先级），但需要根据 $qr 把 $condition 计算出来
     * 只有计算了 $condition 之后才可以构成最终的结果以及 $keyword 部分的内容。
     */
    const condFields = Object.keys($terms);
    const condition = __Zn.clone($condition);
    Object.keys(qr).forEach(field => {
        if (0 < field.indexOf(",")) {
            const term = field.split(",")[0];
            if (condFields.includes(term)) {
                const condValue = qr[field];
                if (__Zn.isArray(condValue)) {
                    condition[term] = condValue;
                } else {
                    condition[term] = [condValue];
                }
            }
        }
    });
    response.$condition = condition;
    /*
     * 此处 qr 是提交后数据，带 "" 键值
     */
    qr.connector = qr[""] ? "AND" : "OR";
    if (qr.hasOwnProperty("")) {
        delete qr[""];
    }
    response.$qr = qr;
    __qrKeyword(response, {
        $condition: condition,
        $terms,
    });
    return response;
}
const irSubmit = (reference) => (state = {}, addOn) => {
    const {
        $qr,
    } = state;
    let {
        $queryView,
        $terms,
    } = reference.state;

    const response = __qrFromForm($qr, reference.state);
    $queryView = __Zn.clone($queryView);
    const queryRef = new QQuery($queryView, reference);
    // 高级搜索AND不生效的问题修复，需要将 $qr[""] 中的值设置到环境中
    let combined = __Zn.clone(response.$condition);
    combined[""] = $qr[""];
    const queryCond = __QRP.qrNorm(combined, {terms: $terms});
    queryRef.and(queryCond);
    response.$query = queryRef.to();

    if (addOn) {
        Object.assign(response, addOn);
    }
    return __Zn.of(reference).in(response).future(() => {
        __Zn.dglQrC(reference, true);
        return __Zn.promise(response)
    })
}
export default {
    irSubmit,
    irData,
}